package com.ruoyi.blockchain;

/**
 * 区块链演示类 - 展示区块链核心功能的使用
 */
public class BlockchainDemo {

    public static void main(String[] args) {
        System.out.println("===== 区块链核心机制演示 =====\n");

        try {
            // 1. 创建区块链实例
            System.out.println("1. 创建区块链...");
            Blockchain blockchain = new Blockchain(3, 100.0);  // 难度为3，挖矿奖励100
            System.out.println("区块链创建成功: " + blockchain);
            System.out.println("创世区块哈希: " + blockchain.getLatestBlock().getHash());
            System.out.println();

            // 2. 创建钱包
            System.out.println("2. 创建用户钱包...");
            Wallet aliceWallet = new Wallet();
            Wallet bobWallet = new Wallet();
            Wallet minerWallet = new Wallet();
            
            System.out.println("Alice的钱包地址: " + aliceWallet.getAddress().substring(0, 20) + "...");
            System.out.println("Bob的钱包地址: " + bobWallet.getAddress().substring(0, 20) + "...");
            System.out.println("矿工的钱包地址: " + minerWallet.getAddress().substring(0, 20) + "...");
            System.out.println();

            // 3. 初始化Alice的余额（通过创世区块之后的挖矿奖励）
            System.out.println("3. 初始化用户余额（模拟挖矿奖励）...");
            blockchain.minePendingTransactions(aliceWallet.getPublicKey());
            System.out.println("Alice的初始余额: " + blockchain.getBalanceOfPublicKey(aliceWallet.getPublicKey()));
            System.out.println("Bob的初始余额: " + blockchain.getBalanceOfPublicKey(bobWallet.getPublicKey()));
            System.out.println();

            // 4. 创建交易
            System.out.println("4. 创建交易（Alice向Bob转账）...");
            Transaction transaction1 = aliceWallet.createTransaction(bobWallet.getPublicKey(), 30.0, blockchain);
            if (transaction1 != null) {
                blockchain.addTransaction(transaction1);
                System.out.println("交易创建成功: " + transaction1.getTransactionId().substring(0, 10) + "...");
                System.out.println("Alice转账给Bob: 30.0 个代币");
            }
            System.out.println();

            // 5. 矿工挖矿，打包交易
            System.out.println("5. 矿工挖矿，确认交易...");
            System.out.println("当前交易池中的交易数量: " + blockchain.getPendingTransactions().size());
            System.out.println("开始挖矿...");
            blockchain.minePendingTransactions(minerWallet.getPublicKey());
            System.out.println("挖矿完成！");
            System.out.println("新区块高度: " + blockchain.getLatestBlock().getIndex());
            System.out.println("新区块哈希: " + blockchain.getLatestBlock().getHash().substring(0, 10) + "...");
            System.out.println("矿工获得奖励: " + blockchain.getMiningReward());
            System.out.println();

            // 6. 检查余额更新
            System.out.println("6. 检查账户余额更新...");
            System.out.println("Alice的余额: " + blockchain.getBalanceOfPublicKey(aliceWallet.getPublicKey()));
            System.out.println("Bob的余额: " + blockchain.getBalanceOfPublicKey(bobWallet.getPublicKey()));
            System.out.println("矿工的余额: " + blockchain.getBalanceOfPublicKey(minerWallet.getPublicKey()));
            System.out.println();

            // 7. 验证区块链完整性
            System.out.println("7. 验证区块链完整性...");
            boolean isValid = blockchain.isChainValid();
            System.out.println("区块链是否有效: " + isValid);
            System.out.println();

            // 8. 创建更多交易
            System.out.println("8. 创建更多交易...");
            Transaction transaction2 = bobWallet.createTransaction(aliceWallet.getPublicKey(), 10.0, blockchain);
            Transaction transaction3 = aliceWallet.createTransaction(bobWallet.getPublicKey(), 5.0, blockchain);
            
            if (transaction2 != null) blockchain.addTransaction(transaction2);
            if (transaction3 != null) blockchain.addTransaction(transaction3);
            
            System.out.println("新增2笔交易，当前交易池中的交易数量: " + blockchain.getPendingTransactions().size());
            System.out.println();

            // 9. 再次挖矿
            System.out.println("9. 再次挖矿，确认更多交易...");
            blockchain.minePendingTransactions(minerWallet.getPublicKey());
            System.out.println("挖矿完成！");
            System.out.println("区块链当前长度: " + blockchain.getChainLength());
            System.out.println("最新区块哈希: " + blockchain.getLatestBlock().getHash().substring(0, 10) + "...");
            System.out.println();

            // 10. 最终余额
            System.out.println("10. 最终账户余额...");
            System.out.println("Alice的最终余额: " + blockchain.getBalanceOfPublicKey(aliceWallet.getPublicKey()));
            System.out.println("Bob的最终余额: " + blockchain.getBalanceOfPublicKey(bobWallet.getPublicKey()));
            System.out.println("矿工的最终余额: " + blockchain.getBalanceOfPublicKey(minerWallet.getPublicKey()));
            System.out.println();

            // 11. 展示区块链中的区块信息
            System.out.println("11. 区块链区块概览...");
            for (Block block : blockchain.getChain()) {
                System.out.println("区块高度: " + block.getIndex());
                System.out.println("  时间戳: " + block.getTimestamp());
                System.out.println("  交易数量: " + block.getTransactions().size());
                // 安全地获取哈希值的前10个字符
                String hash = block.getHash();
                String displayHash = hash.length() >= 10 ? hash.substring(0, 10) : hash;
                System.out.println("  区块哈希: " + displayHash + "...");
                // 安全地获取前一区块哈希的前10个字符
                String prevHash = block.getPreviousHash();
                String displayPrevHash = prevHash != null && prevHash.length() >= 10 ? prevHash.substring(0, 10) : prevHash;
                System.out.println("  前一区块哈希: " + displayPrevHash + "...");
                System.out.println("  Nonce: " + block.getNonce());
            }
            System.out.println();

            System.out.println("===== 区块链核心机制演示完成 =====");

        } catch (Exception e) {
            System.err.println("演示过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}